package ch.simplix.android.repetitive.implementation;

import java.util.concurrent.TimeUnit;

import android.util.Log;
import ch.simplix.android.repetitive.definition.RepeaterAction;
import ch.simplix.android.repetitive.definition.RepeaterStrategy;

/**
 * This {@link RepeaterStrategy} is very usable for repetition-delays between
 * 0.01secs and 1 second. The system is kept running via a
 * {@link Thread#sleep(long)}.
 * 
 * @author SimpliX
 * 
 */
public class SleepRepeaterStrategy extends ARepeaterStrategy {
	private final static String TAG = SleepRepeaterStrategy.class
			.getSimpleName();

	private Thread thread;
	private final Runnable updateTimeTask;
	private boolean isRunning;

	/*
	 * (non-Javadoc)
	 * 
	 * @see ch.simplix.android.repetitive.service.RepeaterStrategy#isRunning()
	 */
	@Override
	public boolean isRunning() {
		return isRunning;
	}

	public SleepRepeaterStrategy(RepeaterAction repeaterAction) {
		super(repeaterAction);
		updateTimeTask = new UpdateTimeTask();

	}

	/**
	 * Android probably never calls this method. So 'we have to' call it.
	 * 
	 * @see ch.simplix.android.repetitive.service.RepeaterStrategy#finalize()
	 */
	@Override
	public void finalize() {
		stopTimedRepetition();
		thread = null;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * ch.simplix.android.repetitive.service.RepeaterStrategy#startTimedRepetition
	 * ()
	 */
	@Override
	public void startTimedRepetition() {
		Log.i("Strategy", "++++++++++Sleep");
		if (thread != null && thread.isAlive())
			return;
		isRunning = true;
		thread = new Thread(updateTimeTask);
		thread.start();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * ch.simplix.android.repetitive.service.RepeaterStrategy#stopTimedRepetition
	 * ()
	 */
	@Override
	public synchronized void stopTimedRepetition() {
		isRunning = false;
		if (thread != null)
			thread.interrupt();
		setUpdateInterval(0, TimeUnit.SECONDS);
	}


	@Override
	protected void prepareRepetition(){
		if (thread != null){
			Log.d(TAG,"prepareRepetition: interrupt");
			thread.interrupt();
		}
			
	}

	class UpdateTimeTask implements Runnable {
		@Override
		public void run() {
			try {
				WakeLockManager.s_acquire();
				while (isRunning()) {
					long updateInterval = getUpdateIntervalInMillis();
					if (updateInterval == 0) {
						stopTimedRepetition();
						continue;
					}

					try {
						Log.d(TAG,
								"" + Math.max(0, updateInterval));
						Thread.sleep(updateInterval, 0);
					} catch (InterruptedException ex) {
						Log.d(TAG, "Interrupted");
					}
					if (isRunning()) {					
						act();
					}
				}
			} finally {
				WakeLockManager.s_release();
			}
		}

	}

}
